#include "GRawInputDeviceMouse.h"
#include "GInput/GInput.h"
#include "GInput/GInputDefinitions.h"
#include "GUtilities/GBitContainer.h"
#include "GUtilities/GError.h"
#include "GUtilities/GTypes.h"


namespace GRawInput
{
	GRawInputDeviceMouse::GRawInputDeviceMouse(GEngine::GModule* Owner, void* Handle)
		: GInputDeviceMouse(Owner, Handle)
	{
		Reset();
		// Always keep connected
		SetConnected(true);
	}

	GRawInputDeviceMouse::~GRawInputDeviceMouse()
	{
	}

	bool GRawInputDeviceMouse::HandleInput(const RAWINPUT& MouseInput) OVERRIDE
	{
		GUtil::GFlag Flags(MouseInput.data.mouse.usFlags);
		GUtil::GFlag ButtonFlags(MouseInput.data.mouse.usButtonFlags);

		// Fields that are not usefull
		//MouseInput.data.mouse.ulButtons;
		//MouseInput.data.mouse.ulRawButtons;
		//MouseInput.data.mouse.ulExtraInformation;

		// Manage Position
		if (Flags.Contains(MOUSE_MOVE_RELATIVE))
		{
			if (MouseInput.data.mouse.lLastX != 0)
			{
				CurrentState.DiffX = MouseInput.data.mouse.lLastX;
				CurrentState.SemanticStates[GEngine::G_MS_PosX] = true;
			}
			if (MouseInput.data.mouse.lLastY != 0)
			{
				CurrentState.DiffY = MouseInput.data.mouse.lLastY;
				CurrentState.SemanticStates[GEngine::G_MS_PosY] = true;
			}
		}
		if (Flags.Contains(MOUSE_MOVE_ABSOLUTE))
		{
			// Not supported
		}
		if (Flags.Contains(MOUSE_VIRTUAL_DESKTOP))
		{
			// Not supported
		}
		if (Flags.Contains(MOUSE_ATTRIBUTES_CHANGED))
		{
			// Not supported
		}
		
		// Manage Buttons
		if (ButtonFlags.Contains(RI_MOUSE_WHEEL))
		{
			if (MouseInput.data.mouse.usButtonData != 0)
			{
				// Scroll data can be negative, cast to signed
				CurrentState.DiffZ = (GInt32)((SHORT)MouseInput.data.mouse.usButtonData);
				CurrentState.SemanticStates[GEngine::G_MS_PosZ] = true;
			}
		}
		if (ButtonFlags.Contains(RI_MOUSE_BUTTON_1_DOWN))
		{
			CurrentState.SemanticStates[GEngine::G_MS_Button0] = true;
		}
		if (ButtonFlags.Contains(RI_MOUSE_BUTTON_1_UP))
		{
			CurrentState.SemanticStates[GEngine::G_MS_Button0] = false;
		}
		if (ButtonFlags.Contains(RI_MOUSE_BUTTON_2_DOWN))
		{
			CurrentState.SemanticStates[GEngine::G_MS_Button2] = true;
		}
		if (ButtonFlags.Contains(RI_MOUSE_BUTTON_2_UP))
		{
			CurrentState.SemanticStates[GEngine::G_MS_Button2] = false;
		}
		if (ButtonFlags.Contains(RI_MOUSE_BUTTON_3_DOWN))
		{
			CurrentState.SemanticStates[GEngine::G_MS_Button1] = true;
		}
		if (ButtonFlags.Contains(RI_MOUSE_BUTTON_3_UP))
		{
			CurrentState.SemanticStates[GEngine::G_MS_Button1] = false;
		}
		if (ButtonFlags.Contains(RI_MOUSE_BUTTON_4_DOWN))
		{
			CurrentState.SemanticStates[GEngine::G_MS_Button3] = true;
		}
		if (ButtonFlags.Contains(RI_MOUSE_BUTTON_4_UP))
		{
			CurrentState.SemanticStates[GEngine::G_MS_Button3] = false;
		}
		if (ButtonFlags.Contains(RI_MOUSE_BUTTON_5_DOWN))
		{
			CurrentState.SemanticStates[GEngine::G_MS_Button4] = true;
		}
		if (ButtonFlags.Contains(RI_MOUSE_BUTTON_5_UP))
		{
			CurrentState.SemanticStates[GEngine::G_MS_Button4] = false;
		}

		return true;
	}

}